package com.dding.cms.base.dao.impl;

import static com.dding.cms.base.web.ActionConstants.WIDGET_FIELF_SEPERATOR;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.javalite.activejdbc.Association;
import org.javalite.activejdbc.LazyList;
import org.javalite.activejdbc.Model;
import org.javalite.activejdbc.Registry;
import org.javalite.activejdbc.associations.BelongsToAssociation;

import com.dding.cms.base.entity.Content;
import com.dding.cms.base.entity.ContentAttr;
import com.dding.cms.base.web.widget.IWidgetContext;
import com.dding.cms.base.web.widget.IWidgetHandler;
import com.dding.cms.base.web.widget.WidgetContext;
import com.dding.cms.base.web.widget.WidgetUtils;

public class ContentEditDaoHandler extends AbstractDaoHandler<Object, Object> {

	private static Set<String> colums;

	@Override
	public Map<String, Object> handleField(Map<String, Object> dataMap,
			Model model) throws Throwable {

		colums = WidgetUtils.getContentColumns();
		Map<String, Object> returnValue = new HashMap<String, Object>();
		Map<String, Object> para = new HashMap<String, Object>();
		for (Object column : colums) {
			String col = (String) column;
			IWidgetHandler handler = controller
					.getWidgetByTableField(getId(col));
			if (handler == null) {
				returnValue.put(col, model.get(col));
				continue;
			}
			para.put(col, model.get(col));
			IWidgetContext widgetContext = new WidgetContext(para);
			Object[] result = (Object[]) handler.handleGet(widgetContext);
			if (result != null && result.length == 2) {
				returnValue.put((String) result[0], result[1]);
			} else {
				returnValue.put(col, model.get(col));
			}
		}
		return returnValue;
	}

	private String getId(String col) {
		return Content.getTableName() + WIDGET_FIELF_SEPERATOR + col;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> handleAssocaition(Map<String, Object> dataMap,
			List<Model> list, Model model) throws Throwable {

		Map<String, Object> valueResult = new HashMap<String, Object>();
		List<Association> associations = Content.associations();
		for (Association association : associations) {
			if (association instanceof BelongsToAssociation) {
				continue;
			}
			Class<? extends Model> clazz = Registry.instance()
					.getMetaModel(association.getTarget()).getModelClass();
			handleAssociation(model.getAll(clazz), valueResult,
					association.getTarget());
		}
		return valueResult;
	}

	@SuppressWarnings("unchecked")
	private void handleAssociation(LazyList<? extends Model> list,
			Map<String, Object> returnValue, String table) {

		if (list == null || list.size() == 0)
			return;

		Map<String, Object> para = new HashMap<String, Object>();
		IWidgetHandler handler = controller.getWidgetByTable(table);
		if (handler == null) {
			return;
		}
		para.put(table, list);
		IWidgetContext widgetContext = new WidgetContext(para);
		Object result = handler.handleGet(widgetContext);
		if (result == null) {
			return;
		} else if (result instanceof Object[]) {
			Object[] temp = (Object[]) result;
			if (temp.length == 2) {
				returnValue.put((String) temp[0], temp[1]);
			}
		} else if (result instanceof Map) {
			returnValue.putAll((Map<String, List<Object>>) result);
		}
	}

	@Override
	public Map<String, Object> handleExtAttr(Map<String, Object> dataMap,
			List<Model> list, Model model) throws Throwable {

		Map<String, Object> valueResult = new HashMap<String, Object>();
		LazyList<? extends Model> attrs = model.getAll(ContentAttr.class);
		Map<String, Object> parameter = new HashMap<String, Object>();

		for (Model attr : attrs.toArray(new Model[0])) {

			String key = (String) attr.get("attr_name");
			Object value = attr.get("attr_value");

			IWidgetHandler handler = controller
					.getWidgetByTableField(getId(key));
			if (handler == null) {
				valueResult.put(key, value);
				continue;
			}
			parameter.put(key, value);
			IWidgetContext widgetContext = new WidgetContext(parameter);
			Object[] result = (Object[]) handler.handleGet(widgetContext);
			if (result != null && result.length == 2) {
				valueResult.put((String) result[0], result[1]);
			} else {
				valueResult.put(key, value);
			}
		}
		return valueResult;
	}
}
